iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0

這篇文章我們來談一下 Origin 如何搭配 CloudFront 做相關保護。

背景

CDN 的一個特性是隱藏 Origin 的實際位置,在 Client 端查詢域名/使用 CloudFront 的過程中,除非 Origin 在回覆的過程中提供了資訊,比方說回應標頭 or 內容中攜帶了 Origin 位於何處的特定資訊,不然 Client 端無法在這過程中取得 Origin 在哪的信息。

而使用 CloudFront 時,你的源站可以是 ELB, 也可以是 S3, 甚至是 EC2、API G/W。基於 Origin 必須讓 CloudFront 能夠存取到,CloudFront 才能進而協助緩存內容,有時會跟著帶來一些「這樣我的 Origin 不就有點不安全?我可不可以限制只有來自 CloudFront 的請求才能抓取資料」的疑問。

可能解法

天底下沒有一個萬能的解法,所以面對這次的需求(可不可以限制只有來自 CloudFront 的請求才能抓取資料),我將以以下可能需要保護的作法說明。

  • 舊作法: 透過 lambda 更新 Security Group
  • 新作法: CloudFront origin-facing Prefix List
  • Custom Header

p.s.
如果您想進一步瞭解 DDoS 類的防護,可以參考 AWS 的公開文件


防止 Client 跳過 CloudFront 直接存取 Origin
雖然 CloudFront 在處理請求時不會揭露 Origin 位於網路上何處的資訊,但在實務中,你的 Origin 位置還是可以被外人(有心人?) 知道了。
此時除了三不五時就會來掃你 Origin 的 Bot(ex: Google) 外,還會有不速之客過來。
那麼,我們可以透過 Security Group 來達成嗎?
答案是可以。

舊作法: 透過訂閱 AWS IP Pool 調整通知,將 AWS CloudFront 的 IP Set 設置到獨立的 SecurityGroup,並讓您的 Origin 僅開放在這 IP Set 的來存取。舊作法的公開文件

而既然是舊作法,有些限制/沒那麼好的部分需要改善,所以當你打開文件時,會看到下面資訊。
https://ithelp.ithome.com.tw/upload/images/20230917/201625023JmmuLtlxW.png

對的,有比較新的作法,叫做 Prefix List

新作法(Prefix List):

仔細想想,CloudFront是一個規模相當大的服務,所以 CloudFront 很理所當然地會將來 與 Client溝通「a.k.a. 收請求+回資料」 與 前往 Origin「a.k.a.發請求+收資料」 的 Traffic 分開。這邊的 Prefix list,就是指「發請求+收資料」這部分。

接下來我們來進一步瞭解怎麼做。
這部分其實非常簡單,幾步驟就可以完成。

  1. 登入你的 EC2 Console,點到 EC2 的 Seucurity Group,修改其中 rule。
  2. 增加一組 inbounnd rule,Protocol/Port 選擇對應你的 Origin 對外提供的 port. (ex: 80)。
  3. Source 選擇 'Custom',接著點選右邊的空格,此時會出現下拉選單,選到 'com.amazonaws.global.cloudfront-origin-facing| pl-xxxxxx' 這組 prefix list
  4. (Optional) 如果你的 security group 有 rule 也是同樣的 Port,但 source 是 Anywhere-IPv4,請記得拿掉
    https://ithelp.ithome.com.tw/upload/images/20230917/20162502vKlA9IRgzA.png

使用 Custom Header

「如果,我是說如果,我不想使用 Security Group 直接攔下來,我可以怎麼做?」
可以的,有依方法是透過 Customer Header。
這是在你設置 CloudFront 的 Origin 的選項,預設沒有開啟。
https://ithelp.ithome.com.tw/upload/images/20230917/20162502SMtZ36w9R6.png

這功能讓 CloudFront 對 Origin 發請求時,在請求中帶上特定 Header,比方說我們可以要求 CloudFront 回源時要帶一個特別的字串,讓 Origin 可以拿來判斷是否是合法的請求。(「站住、口令、誰」的概念)。
我們用以下步驟來設置+測試

  1. 登入 CloudFront Console,Edit Distribution,接著選到 Origin 進行修改。
  2. 新增一組 Custom Header & 對應值,這邊以 'x-kgg23' 為 header,對應值為 'ilovecf'
    https://ithelp.ithome.com.tw/upload/images/20230917/20162502fyQiNgZQJq.png
  3. 完成 CloudFront 這端的修改後,接著我們要去 Origin 進行修改,我這邊用 ALB(Application Load Balancer) 做舉例[1]
    3.1 登入 EC2 Console,選到對應的 ALB,選到 'Listeners and rules' 的 tab
    3.2 點選想要修改的 listener,然後點 'Add Rule'。添加 Tag 時可以加上你希望給的名字,按下一步。
    3.3 點選 'Add Condition',將 HTTP Header & 值填上
    https://ithelp.ithome.com.tw/upload/images/20230917/20162502nmYXQ5B1yv.png
    3.4 設定符合條件時的動作: 轉發給原本就服務的 TargetGroup。
    3.5 設定 Priority,數值越小,優先等級越高
    https://ithelp.ithome.com.tw/upload/images/20230918/20162502GEZ54TbaYe.png
    3.6 重要 記得此時要修改「預設」的行為,因為「有帶正確的 Header/Value」的請求已經被轉發給對應的 TargetGroup,所以要讓「預設」行為改為固定回應 (Fixed Response,比方說 403)
    https://ithelp.ithome.com.tw/upload/images/20230918/20162502mrGAXl5UDZ.png

那麼,我們就可以依照 CloudFront 端設定 Custom Header,搭配 Origin ALB 的 Routing Rules,將不是來自 CloudFront 的請求都阻攔在外。

恭喜你,你也跟著我一起完成 Day 15 囉。

[1] 如果你不是使用 ALB,而是直接用 EC2+Nginx 提供服務,可以參考這設置,這段設置代表如果

#if the header 'x-kgg23' is not presented, or the value is not 'kenex'
#nginx returns 403. 
if ($http_x_kgg23 !~ "ilovecf") {
    return 403;
}

參考來源: 這文件


上一篇
Day 14 - CloudFront 的 Policy 是什麼,該怎麼用? (下篇)
下一篇
Day 16 - 讓 CloudFront 搭配 WAF
系列文
2023 年了,一起來學 CDN - 你也可以瞭解的 CloudFront 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言